package main

import "fmt"

// 如果你需要在访问一个对象时，有一个像“代理”一样的角色，
// 她可以在访问对象之前为你进行缓存检查、权限判断等访问控制，
// 在访问对象之后为你进行结果缓存、日志记录等结果处理，那么就可以考虑使用代理模式
type Subject0 interface {
	Proxy() string
}
type Proxy struct {
	real RealSubject
}

func (p Proxy) Proxy() string {
	var res string
	// 在调用真实对象之前，检查缓存，判断权限等等
	p.real.Pre()
	// 调用真实对象
	p.real.Real()
	// 调用之后的操作，缓存结果，记录日志等等
	p.real.After()

	return res
}

type RealSubject struct{}

func (RealSubject) Real() {
	fmt.Print("real")
}
func (RealSubject) Pre() {
	fmt.Print("pre:")
}
func (RealSubject) After() {
	fmt.Print(":after")
}

func ExampleProxy() {
	// var sub Subject
	sub := &Proxy{}
	sub.Proxy()
}
